package com.kkwrite.regimen.provider.controller.income;

import com.kkwrite.regimen.common.entity.dto.OutDTO;
import com.kkwrite.regimen.common.entity.dto.income.PageableIncomeDTO;
import com.kkwrite.regimen.common.entity.dto.income.ShopExtractCashInDTO;
import com.kkwrite.regimen.provider.exception.DBNullException;
import com.kkwrite.regimen.provider.exception.ExtractCashException;
import com.kkwrite.regimen.provider.exception.ServiceException;
import com.kkwrite.regimen.provider.service.income.IncomeService;
import com.kkwrite.regimen.provider.service.income.ShopIncomeService;
import com.kkwrite.regimen.provider.util.TokenUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static com.kkwrite.regimen.common.constant.Constant.BOOLEAN_STRING_FALSE;
import static com.kkwrite.regimen.common.constant.Constant.BOOLEAN_STRING_TRUE;

/**
 * 收益明细
 *
 * @author jinying
 */
@Api(value = "收益模块")
@RestController
@RequestMapping("/income")
public class IncomeController {

    private static final Logger logger = LoggerFactory.getLogger(IncomeController.class);

    @Resource(name = "incomeService")
    private IncomeService incomeService;
    @Resource(name = "shopIncomeService")
    private ShopIncomeService shopIncomeService;
    @Resource(name = "tokenUtil")
    private TokenUtil tokenUtil;

    @GetMapping("/getIncome")
    public OutDTO<PageableIncomeDTO> getIncome(Integer page, Integer size, Long userId, Integer sortType) {
        OutDTO<PageableIncomeDTO> outDTO = new OutDTO<>();
        try {
            PageableIncomeDTO pageableIncomeDTO = incomeService.queryIncome(page, size, userId, sortType);
            outDTO.setSuccess("true");
            outDTO.setData(pageableIncomeDTO);
            return outDTO;
        } catch (ServiceException e) {
            logger.error(e.getMessage(), e);
            return new OutDTO<>(BOOLEAN_STRING_FALSE, e.getMessage());
        } catch (Exception e) {
            return OutDTO.of(BOOLEAN_STRING_FALSE, "服务异常", null, null);
        }
    }

    @GetMapping(value = "/count/{userId}")
    public OutDTO countIncome(@PathVariable Long userId) {
        try {
            return OutDTO.of(BOOLEAN_STRING_TRUE, "OK", "OK", incomeService.count(userId));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return OutDTO.of(BOOLEAN_STRING_FALSE, "统计用户收益服务异常！异常信息：" + e.getMessage());
        }
    }

    @GetMapping(value = "/extract/{userId}")
    public OutDTO extractCash(@RequestParam Double amount, @PathVariable Long userId) {
        try {
            incomeService.extractCash(amount, userId);
            return OutDTO.of(BOOLEAN_STRING_TRUE, "OK", "OK", null);
        } catch (DBNullException e) {
            return OutDTO.of(BOOLEAN_STRING_FALSE, "可用余额不足");
        } catch (ExtractCashException e) {
            return OutDTO.of(BOOLEAN_STRING_FALSE, e.getMessage());
        } catch (Exception e) {
            return OutDTO.of(BOOLEAN_STRING_FALSE, "服务异常！异常信息：" + e.getMessage());
        }
    }

    @PostMapping(value = "/extractcash")
    @HystrixCommand(fallbackMethod = "extractCashOfShopError")
    @ApiOperation(value = "店铺提现接口")
    @ApiImplicitParam(name = "inDTO", value = "封装提现金额amount", required = true,
            paramType = "body", dataType = "ShopExtractCashInDTO")
    public OutDTO extractCashOfShop(@RequestBody ShopExtractCashInDTO inDTO, HttpServletRequest request) {
        String shopId = (String) tokenUtil.getValue(request.getHeader("token"), TokenUtil.TokenKeyEnum.SHOP_ID);
        if (shopId == null) {
            return OutDTO.of(BOOLEAN_STRING_FALSE, "002", "token invalid");
        }
        if (inDTO == null || inDTO.isInvalid()) {
            throw new RuntimeException("入参不合法");
        }
        shopIncomeService.extractCashOfShop(inDTO.getAmount(), Long.valueOf(shopId));
        return OutDTO.of(BOOLEAN_STRING_TRUE, "OK", "OK", null);
    }

    public OutDTO extractCashOfShopError(ShopExtractCashInDTO inDTO, HttpServletRequest request, Throwable t) {
        return OutDTO.of(BOOLEAN_STRING_FALSE, "商铺发起提现异常！异常信息：" + t.getMessage(), null, inDTO);
    }

    @ApiOperation(value = "店铺收益统计接口")
    @GetMapping(value = "/shop/count")
    @HystrixCommand(fallbackMethod = "countShopIncomeError")
    public OutDTO countShopIncome(@ApiIgnore @RequestHeader String token) {
        String shopIdString = (String) tokenUtil.getValue(token, TokenUtil.TokenKeyEnum.SHOP_ID);
        if (shopIdString == null) {
            return OutDTO.of(BOOLEAN_STRING_FALSE, "002", "token invalid");
        }
        return OutDTO.of(BOOLEAN_STRING_TRUE, "OK", "OK", shopIncomeService.count(shopIdString));
    }

    public OutDTO countShopIncomeError(String token, Throwable t) {
        logger.error(t.getMessage(), t);
        return OutDTO.of(BOOLEAN_STRING_FALSE, "商户收益统计接口服务异常！异常信息：" + t.getMessage());
    }

}
